package com.fun.feifun.modules.sys;


import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Handle;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Util;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.fun.feifun.base.result.Result;
import com.fun.feifun.modules.sys.auth.model.dto.MenuTree;
import com.fun.feifun.modules.sys.user.model.SysUser;
import com.fun.feifun.modules.sys.user.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static cn.dev33.satoken.stp.StpUtil.getTokenValue;


/**
 * 系统_词典 接口控制器
 *
 * @author wkf
 * @since 2022-04-20
 */
@RestController
@Slf4j
@Api(tags = "登录授权")
@RequestMapping("/sys/auth")
public class AuthController {
    @Autowired
    private ISysUserService userService;

    @PostMapping("/login")
    @ApiOperation(value = "登录")
    public Result login(@NonNull@RequestParam(value="username") String userName,@NonNull @RequestParam(value="password") String password){

        SysUser user = userService.getByUserName(userName);
        if(ObjectUtils.isEmpty(user)){
            return Result.err("用户名或者密码正确");
        }
        if(password.equals(user.getPassword())){
            StpUtil.login(user.getId());
            SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
            return Result.success(tokenInfo);
        }else {
            return Result.err("用户名或者密码正确");
        }
    }

    @ApiOperation(value = "登录")
    public Result loginTenantId( @ApiParam("账号") @RequestParam("username") String userName,
                         @ApiParam("密码") @RequestParam("password") String password,
                         @ApiParam("租户id") @RequestParam(value = "tenantId", required = false, defaultValue = "1") Long tenantId) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>();
        queryWrapper.lambda().eq(SysUser::getUserName, userName);
        SysUser user = userService.getOne(queryWrapper);
        if (ObjectUtils.isEmpty(user)) {
            return Result.err("用户名不存在");
        }
        // MD5加密
        if (!password.equals(user.getPassword())) {
            return Result.err("密码不正确");
        }
        StpUtil.login(user.getId(), String.valueOf(tenantId));
        String tokenValue = getTokenValue();
        return Result.success(tokenValue);
    }



    @SaCheckLogin()
    @GetMapping("/logout")
    @ApiOperation(value = "退出登录")
    public Result logout() {
        StpUtil.logout();
        return Result.success();
    }

    // 处理所有OAuth相关请求
    @RequestMapping("/oauth2/*")
    public Object request() {
        System.out.println("------- 进入请求: " + SaHolder.getRequest().getUrl());
        return SaOAuth2Handle.serverRequest();
    }

    // Sa-OAuth2 定制化配置
    @Autowired
    public void setSaOAuth2Config(SaOAuth2Config cfg) {
        cfg.
                // 配置：未登录时返回的View
                        setNotLoginView(
                        () -> {
                            return new ModelAndView("login.html");
                        })
                        .
                // 配置：登录处理函数
                        setDoLoginHandle(
                        (name, pwd) -> {
                            Result login = loginTenantId(name, pwd, 1L);
                            return login;
                        })
                        .

                // 配置：确认授权时返回的View
                        setConfirmView(
                        (clientId, scope) -> {
                            Map<String, Object> map = new HashMap<>();
                            map.put("clientId", clientId);
                            map.put("scope", scope);
                            map.put("nickName", scope);
                            map.put("username", scope);
                            map.put("phone", scope);
                            map.put("mail", scope);
                            return new ModelAndView("confirm.html", map);
                        });
    }

    // 全局异常拦截
    @ExceptionHandler
    public SaResult handlerException(Exception e) {
        e.printStackTrace();
        return SaResult.error(e.getMessage());
    }

    // 获取Userinfo信息：昵称、头像、性别等等
    @RequestMapping("/oauth2/userinfo")
    public SaResult userinfo() {
        // 获取 Access-Token 对应的账号id
        String accessToken = SaHolder.getRequest().getParamNotNull("access_token");
        Object loginId = SaOAuth2Util.getLoginIdByAccessToken(accessToken);
        System.out.println("-------- 此Access-Token对应的账号id: " + loginId);

        // 校验 Access-Token 是否具有权限: userinfo
        SaOAuth2Util.checkScope(accessToken, "userinfo");

        // 模拟账号信息 （真实环境需要查询数据库获取信息）
        Map<String, Object> map = new LinkedHashMap<String, Object>();
        map.put("nickname", "shengzhang_");
        map.put("avatar", "http://xxx.com/1.jpg");
        map.put("age", "18");
        map.put("sex", "男");
        map.put("address", "山东省 青岛市 城阳区");
        return SaResult.data(map);
    }



}
